/**
 * 
 */
package br.com.salaodebeleza.security;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import br.com.salaodebeleza.business.TbBotaoBC;
import br.com.salaodebeleza.business.TbMenuBC;
import br.com.salaodebeleza.business.TbMenuBotaoBC;
import br.com.salaodebeleza.business.TbUsuarioBC;
import br.com.salaodebeleza.domain.TbBotao;
import br.com.salaodebeleza.domain.TbGrupo;
import br.com.salaodebeleza.domain.TbGrupoMenuBotao;
import br.com.salaodebeleza.domain.TbGrupoMenuBotaoId;
import br.com.salaodebeleza.domain.TbMenu;
import br.com.salaodebeleza.domain.TbMenuBotao;
import br.com.salaodebeleza.domain.TbUsuario;
import br.com.salaodebeleza.exception.PermissionsException;
import br.com.salaodebeleza.persistence.GrupoMenuBotaoDAO;

/**
 * @author tiagofranca
 *
 */
public class Permissions implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	private TbGrupo groupUser;
	private List<TbMenu> menusUser;
	private Map<TbMenu, List<TbMenu>> subMenusUser;
	private Map<TbMenu, List<TbBotao>> menuButtonUser;
	List<TbGrupoMenuBotao> buttonsMenuGroup;
	
	@Inject
	private TbUsuarioBC usuarioBC;
	@Inject
	private TbMenuBotaoBC menuBotaoBC;
	@Inject
	private TbMenuBC menuBC;
	@Inject
	private TbBotaoBC botaoBC;
	
	public void clear() {
		this.groupUser = null;
		this.menusUser = null;
		this.subMenusUser = null;
		this.menuButtonUser = null;
		this.buttonsMenuGroup = null;
	}

	public void loadUserPermissionsAdmin(String userCID) throws PermissionsException {
		TbUsuario user = usuarioBC.getByCDI(userCID);
		groupUser = user.getTbGrupo();
		menusUser = new ArrayList<TbMenu>();
		subMenusUser = new HashMap<TbMenu, List<TbMenu>>();
		
		ArrayList<TbMenu> submenusList = null;		
		for (TbMenu menu : menuBC.findAll()) {
			if(menu.getAtivo().equals("S")){
				menusUser.add(menu);
				if(menu.getTbMenu() == null){
					submenusList = new ArrayList<TbMenu>();
					for(TbMenu menuFilho : menuBC.findAll()){
						if(menuFilho.getTbMenu() != null && menuFilho.getTbMenu().getId() == menu.getId()){
							submenusList.add(menuFilho);
						}
					}
				}
				subMenusUser.put(menu, submenusList);
			}
		}
		
		buttonsMenuGroup = new GrupoMenuBotaoDAO().findAll();
		
		List<TbMenuBotao> buttonsMenu = null;
		ArrayList<TbBotao> validButtonsMenu = null;
		menuButtonUser = new HashMap<TbMenu, List<TbBotao>>();
		
		for (TbMenu menu : menuBC.findAll()) {
			buttonsMenu = retriveButtonsMenu(menu);
			validButtonsMenu = new ArrayList<TbBotao>();
			for (TbMenuBotao menuBotao : buttonsMenu) {
				validButtonsMenu.add(botaoBC.load(menuBotao.getBotao()));
			}
			menuButtonUser.put(menu, validButtonsMenu);
		}
	}
	
	public void loadUserPermissions(String userCID) throws PermissionsException {
		TbUsuario user = usuarioBC.getByCDI(userCID);
		
		groupUser = user.getTbGrupo();
		menusUser = new ArrayList<TbMenu>();
		subMenusUser = new HashMap<TbMenu, List<TbMenu>>();
		
		ArrayList<TbMenu> submenusList = null;		
		
		for (TbMenu menu : groupUser.getTbMenus()) {
			menusUser.add(menu);
		}
		
		for (TbMenu menu : groupUser.getTbMenus()) {
			if(menu.getAtivo().equalsIgnoreCase("S")){
				if(menu.getTbMenu() == null){
					submenusList = new ArrayList<TbMenu>();
					for(TbMenu menuFilho : groupUser.getTbMenus()){
						if(menuFilho.getTbMenu() != null && menuFilho.getTbMenu().getId() == menu.getId()){
							submenusList.add(menuFilho);
						}
					}
				}
				subMenusUser.put(menu, submenusList);
			}
		}
		
		retrieveButtonsMenuGroup();
		List<TbMenuBotao> buttonsMenu = null;
		ArrayList<TbBotao> validButtonsMenu = null;
		menuButtonUser = new HashMap<TbMenu, List<TbBotao>>();
		
		for (TbMenu menu : groupUser.getTbMenus()) {
			buttonsMenu = retriveButtonsMenu(menu);
			validButtonsMenu = new ArrayList<TbBotao>();
			
			for (TbMenuBotao menuBotao : buttonsMenu) {
				if (validatePermissionButton(menuBotao)) {
					validButtonsMenu.add(botaoBC.load(menuBotao.getBotao()));
				}
			}
			
			menuButtonUser.put(menu, validButtonsMenu);
		}
	}
	
	public TbGrupo getUserGroup() {
		return groupUser;
	}
	
	public List<TbMenu> getMenus() {
		return menusUser;
	}
	
	public long retrieveMenuID(String shortURI) {
		boolean searchSubMenu = true;
		long menuID = 0l;
		for (TbMenu m : getMenus()) {
			if (m.getLink() != null && m.getLink().contains(shortURI)) {
				menuID = m.getId();
				break;
			} else {
				if (searchSubMenu && m.getTbMenus() != null) {
					for (TbMenu sm : m.getTbMenus()) {
						if (sm.getLink() != null && sm.getLink().contains(shortURI)) {
							menuID = sm.getId();
							searchSubMenu = false;
							break;
						}
					}
				}
			}
		}
		return menuID;
	}
	
	public boolean containsURL(String url){
		for(TbMenu menu : menusUser){
			if(menu.getLink() != null && menu.getLink().contains(url)){
				if(menu.getTbMenu() != null && !containsTbMenuParent(menu)){
					return false;
				}else{
					return true;
				}
			}
		}
		return false;
	}
	
	public boolean containsTbMenuParent(TbMenu menu){
		for(TbMenu m : menusUser){
			if(m.getId() == menu.getId()){
				return true;
			}
		}
		return false;
	}
	
	public List<TbMenu> getChildMenu(TbMenu menu) {
		return subMenusUser.get(menu);
	}
	
	public List<TbBotao> getButtonsMenu(TbMenu menu) {
		return menuButtonUser.get(menu);
	}
	
	private void retrieveButtonsMenuGroup() {
		buttonsMenuGroup = new GrupoMenuBotaoDAO().findByGrupoID(groupUser);
	}
	
	private List<TbMenuBotao> retriveButtonsMenu(TbMenu menu) {
		return menuBotaoBC.findByMenuId(menu.getId());
	}
	
	private boolean validatePermissionButton(TbMenuBotao menuBotao) {
		TbGrupoMenuBotaoId idButtonsMenuGroup = new TbGrupoMenuBotaoId();
		idButtonsMenuGroup.setGrupo(groupUser.getId());
		idButtonsMenuGroup.setMenuBotao(menuBotao.getId());
		TbGrupoMenuBotao buttonsMenuGroupTemp = new TbGrupoMenuBotao();
		buttonsMenuGroupTemp.setId(idButtonsMenuGroup);
		return buttonsMenuGroup.contains(buttonsMenuGroupTemp);
	}
}
